home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_11 / pjp / ospad.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-02  |  2.4 KB  |  94 lines

  1. ------------- Listing 5: The file ospad.c -----------------
  2.  
  3. // ospad -- ostream padding members 
  4. #include <string.h> 
  5. #include <ostream> 
  6.  
  7. static _Bool do_rep(streambuf *sb, char c, int n) 
  8.     {    // put repeated char 
  9.     while (0 <= --n) 
  10.         if (sb->sputc(c) == EOF) 
  11.             return (0); 
  12.     return (1); 
  13.     } 
  14.  
  15. inline _Bool rep(streambuf *sb, char c, int n) 
  16.     {    // put repeated char, if any 
  17.     return (0 < n ? do_rep(sb, c, n) : 1); 
  18.     } 
  19.  
  20. inline _Bool send(streambuf *sb, const char *s, int n) 
  21.     {    // put char sequence, if any 
  22.     return (n <= 0 || sb->sputn(s, n) == n ? 1 : 0); 
  23.     } 
  24.  
  25. void ostream::_Pad(const char *code, char *s, int n) 
  26.     {    // pad with fill char as needed 
  27.     _Bool ok = 1; 
  28.     int ni, np, nz; 
  29.     const char *sf; 
  30.     const void *sv; 
  31.     if (code[1] != '.' || (nz = precision() - _Pr()) <= 0) 
  32.         nz = 0, sf = s + n; 
  33.     else if ((sv = memchr((const void *)s, 'e', n)) != 0 
  34.         || (sv = memchr((const void *)s, 'E', n)) != 0) 
  35.         sf = (const char *)sv; 
  36.     else 
  37.         sf = s + n; 
  38.     ni = sf - s; 
  39.     if (width() == 0 || (np = width() - n - nz) < 0) 
  40.         np = 0; 
  41.     if ((flags() & adjustfield) == right) 
  42.         {    // put leading fill 
  43.         if (!rep(rdbuf(), fill(), np) 
  44.             || !send(rdbuf(), s, ni) 
  45.             || !rep(rdbuf(), '0', nz) 
  46.             || !send(rdbuf(), sf, n - ni)) 
  47.             ok = 0; 
  48.         } 
  49.     else if ((flags() & adjustfield) != internal) 
  50.         {    // put trailing fill 
  51.         if (!send(rdbuf(), s, ni) 
  52.             || !rep(rdbuf(), '0', nz) 
  53.             || !send(rdbuf(), sf, n - ni) 
  54.             || !rep(rdbuf(), fill(), np)) 
  55.             ok = 0; 
  56.         } 
  57.     else if (code[0] == 'B' && code[3] == 'x' && 2 <= n 
  58.         && (s[1] == 'x' || s[1] == 'X')) 
  59.         {    // put internal fill after 0x or 0X 
  60.         if (!send(rdbuf(), s, 2) 
  61.             || !rep(rdbuf(), fill(), np) 
  62.             || !send(rdbuf(), s + 2, ni - 2)) 
  63.             ok = 0; 
  64.         } 
  65.     else if (0 < n && (s[0] == '-' || s[0] == '+')) 
  66.         {    // put internal fill after + or - 
  67.         if (!send(rdbuf(), s, 1) 
  68.             || !rep(rdbuf(), fill(), np) 
  69.             || !send(rdbuf(), s + 1, ni - 1) 
  70.             || !rep(rdbuf(), '0', nz) 
  71.             || !send(rdbuf(), sf, n - ni - 1)) 
  72.             ok = 0; 
  73.         } 
  74.     else 
  75.         {    // put internal fill as leading fill 
  76.         if (!rep(rdbuf(), fill(), np) 
  77.             || !send(rdbuf(), s, ni) 
  78.             || !rep(rdbuf(), '0', nz) 
  79.             || !send(rdbuf(), sf, n - ni)) 
  80.             ok = 0; 
  81.         } 
  82.     width(0); 
  83.     if (!ok) 
  84.         setstate(badbit); 
  85.     } 
  86.  
  87. int ostream::_Pr() 
  88.     {    // get bounded precision 
  89.     return (precision() <= 0 && !(flags() & fixed) ? 6 
  90.         : _MAX_SIG_DIG < precision() ? _MAX_SIG_DIG 
  91.         : precision()); 
  92.     }
  93.  
  94.